Repository navigation
Run released workflows with the current run, resume, revise and verify (#271) - #289
Merged
Merged
Conversation
#271) The Workflows family of the persisted-contracts D rows, part 2a. No new fixtures and no src change: the v0.2.0 and v0.3.0 stores frozen in part 1 are now executed by HEAD. Execution goes through WorkflowCoordinator.run, the call the durable job's worker makes; the hermetic suite starts no job. Fake codex and kimi-code node agents record their prompts. - run of released planned, created and revised rows (a revision leaves its parent runnable): each node gets the stored goal and its own stored prompt, the final node its dependency's output; calls_used continues from the released count; a HEAD final artifact, approved. - resume against the stored absolute deadline, with the clock fixed from the row's own deadline_at (three of these rows were stored without a heartbeat). After it: every crash and failure ends "workflow deadline exceeded" before any dispatch, deadline unchanged. Before it: a dead owner's run and a recovered one reuse the released draft bundle and refund the killed node's attempt (3 -> 4 calls); a final artifact published before the crash is reused and approved, and v0.2.0's is not backfilled with final_agent; an exhausted node dispatches nothing. Refused from completed, cancelled and planned, and while the released owner's pid lives, where the refused attempt is appended after the released execution history. Events continue the released sequence. - workflow revise: a v0.2.0 parent gains a lineage (its only changed column), a v0.3.0 lineage continues past its last version. - workflow run/resume up to a stubbed launch: the team peek follows default_team for a v0.2.0 row and not for a v0.3.0 row that recorded none; a final state is refused before any launch. - apply --verify of the released final artifact: v0.2.0 gets the gate's own allowlist only, with the notice; v0.3.0 also the final agent's; both also after a prune. - control plans enabled refuse a released workflow planned without one, before any agent or Toolgraph call. The doc row names these; still not yet: release-written control-plan workflows, a bundle saved just before a crash, and an interrupted workflow-origin apply (part 2b, new fixtures). 13 injected regressions in workflow.py and cli.py each fail a test here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 1 found assertions that survived the code they protect: - rendering is now judged by the invocation's own execution: it must be the one appended after the released history, and the same record with its state flipped must print the same outcome (invocation() -> None passed before); - the final artifact's patch and bundle digests are recomputed from the final node's stored bytes (dropping both from the plan passed before); - the control-plan refusal records Toolgraph calls instead of raising from the seam, which run_preflight swallows (an advisory call before the refusal passed before); - run and revise keep every released workflow file and event as written (a truncated planner output passed before); - apply --verify: an unlisted variable never reaches the gate, the common ones and the listed values do. 17 injected regressions now each fail a test here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 2: - rendering is checked against a later, conflicting execution appended to the same record: the outcome stays this invocation's (returning the latest execution passed before, because the round-1 check equated this invocation with the last entry); - resume of the released published final artifact is refused, without approving, replacing or re-running anything, when its patch bytes, plan digests, source fingerprint, node, workflow or repository disagree (the reuse checks could be removed before); - the final node's prompt never carries the draft node's task. 24 injected regressions now each fail a test here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #271. This is the Workflows family, part 2a. Part 1 (#287) froze v0.2.0 and v0.3.0 workflow stores written by each release's own CLI and read them with the current readers. This part runs the current
run,resume,reviseandapply --verifyover those same stores. The issue stays open.What
Tests only: no fixture bytes and no source under
src/change.WorkflowCoordinator.run, the call the durable job's worker makes; the hermetic suite starts no job. Fakecodexandkimi-codenode agents record their prompts. Theworkflow run/resumeCLI is tested up to a stubbed job launch.runof releasedplanned,createdandrevisedrows (a revision leaves its parent runnable):calls_usedcontinues from the released count;resumeagainst the stored absolute deadline. The clock is fixed from the row's owndeadline_at, because three of these rows were stored without a heartbeat.workflow deadline exceededbefore any dispatch, with the deadline unchanged.final_agent. It is refused, without approving, replacing or re-running anything, when its patch bytes, plan digests, source fingerprint, node, workflow or repository disagree.no runnable nodes remain before final_node completed.completed,cancelledandplanned, and while the released owner's pid lives. A refused takeover appends a failedresumeexecution after the released history and changes nothing else.workflow revise: a v0.2.0 parent gains a lineage, its only changed column; a v0.3.0 lineage continues past its last version.default_teamfor a v0.2.0 row and not for a v0.3.0 row that recorded none. A final state is refused before any launch.apply --verifyof the released final artifact, also after a prune:verify:notice;docs/architecture/persisted-contracts.md: the Workflows row names these.No current reader or executor misread a released workflow.
Part 2b (not here; still "not yet" in the row). Each needs new release-written fixtures:
Verification
suite-runCLEAN;ruff check .clean.workflow.pyandcli.pyeach fail an intended assertion. They include:invocation()returning nothing or the latest entry;3e40cda.run_preflightswallows.0cf71ad.🤖 Generated with Claude Code